package org.openkanban.server.dao.impl;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.openkanban.server.dao.UserDao;
import org.openkanban.server.domain.User;
import org.openkanban.shared.util.StatusCodes;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

/**
 * jpa implementation of user data access object
 */
@Repository
public class UserDaoJpaImpl implements UserDao {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public boolean authentificate(User user) {
	Query query = entityManager.createQuery("SELECT u FROM User u WHERE email=:email AND password=:password");
	query.setParameter("email", user.getEmail());
	query.setParameter("password", user.getPassword());
	@SuppressWarnings("unchecked")
	List<User> ul = (List<User>) query.getResultList();
	if (ul.isEmpty()) {
	    return false;
	}
	user.setUserId(ul.get(0).getUserId());
	return true;
    }

    @Override
    @Transactional
    public User createUser(User user) {
	entityManager.persist(user);
	return user;
    }

    public String test() {
	return "test";
    }

    @Override
    public User getUser(Long id) {
	return entityManager.find(User.class, id);
    }

    @Override
    @SuppressWarnings("unchecked")
    public User getUser(String eMail) {
	Query query = entityManager.createQuery("SELECT u FROM User u WHERE email=:email");
	query.setParameter("email", eMail);
	List<User> user = query.getResultList();
	if (user == null || user.size() < 1) {
	    return null;
	}
	return user.iterator().next();
    }

    @Override
    public User[] getContacts(Long userId) {

	User parentUser = getUser(userId);
	if (parentUser.getKontakteEmailList() == null) {
	    return null;
	}

	return parentUser.getKontakteEmailList().toArray(new User[] {});

    }

    @Override
    @Transactional
    public StatusCodes addContact(String parentUserId, String eMail) {
	User user = getUser(Long.parseLong(parentUserId));
	User contact = getUser(eMail);

	if (contact == null) {
	    return StatusCodes.INVALID_INPUT_DATA;
	}

	if (contact != null && user != null) {
	    if (user.getKontakteEmailList().contains(contact)) {
		return StatusCodes.DUPLICATE_ENTRY;
	    }

	    user.addContact(contact);
	    entityManager.merge(user);
	    return StatusCodes.OK;
	}
	return StatusCodes.DATABASE_ERROR;
    }

    @Override
    @Transactional
    public StatusCodes removeContact(User user, String eMail) {
	User parentUser = entityManager.find(User.class, user.getUserId());

	User contact = getUser(eMail);

	if (contact != null) {
	    if (parentUser.removeContact(contact)) {
		entityManager.merge(parentUser);
		return StatusCodes.OK;
	    } else {
		return StatusCodes.FEHLER_BEIM_ENTFERNEN;
	    }
	}
	return StatusCodes.DATABASE_ERROR;
    }

    @Override
    @Transactional
    public StatusCodes updateUser(User user) {
	entityManager.merge(user);
	return StatusCodes.OK;
    }

}
